package com.wzb.mybatisplus.bitaction.electrumaction;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.io.*;
import java.net.Socket;
import java.util.Iterator;

public class ElectrumJavaClient12 {

    private static final String ELECTRUM_SERVER_HOST = "127.0.0.1"; // 示例公共服务器
    private static final int ELECTRUM_SERVER_PORT = 50001; // TCP 端口 (未加密！)

    private Socket socket;
    private BufferedReader reader;
    private BufferedWriter writer;
    private ObjectMapper mapper;
    private int requestId = 0;

    public static void main(String[] args) {
        ElectrumJavaClient12 client = new ElectrumJavaClient12();

        try {
            client.connect();

            // 替换成你想要查询的比特币地址
            String bitcoinAddress = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa";

            // 1. 查询余额
            String balance = client.getBalance(bitcoinAddress);
            System.out.println("地址 " + bitcoinAddress + " 的余额: " + balance);

            // 2. 查询交易历史
            System.out.println("\n交易历史:");
            String history = client.getHistory(bitcoinAddress);
            System.out.println(history);

            client.disconnect();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void connect() throws IOException {
        System.out.println("正在连接到 Electrum 服务器...");
        socket = new Socket(ELECTRUM_SERVER_HOST, ELECTRUM_SERVER_PORT);
        reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        mapper = new ObjectMapper();

        // 可选：发送 server.version 协议握手
        String versionResponse = sendRequest("server.version", mapper.createArrayNode().add("electrum-java-client").add("1.4"));
        System.out.println("服务器版本: " + versionResponse);
    }

    public void disconnect() throws IOException {
        if (reader != null) reader.close();
        if (writer != null) writer.close();
        if (socket != null) socket.close();
        System.out.println("连接已断开。");
    }

    /**
     * 发送 JSON-RPC 请求并返回结果
     */
    private String sendRequest(String method, ArrayNode params) throws IOException {
        ObjectNode request = mapper.createObjectNode();
        request.put("id", requestId++);
        request.put("method", method);
        request.set("params", params);
        request.put("jsonrpc", "2.0");

        String requestString = request.toString() + "\n"; // Electrum 协议以换行符结束
        // System.out.println("发送: " + requestString); // 调试用

        writer.write(requestString);
        writer.flush();

        String response = reader.readLine();
        // System.out.println("接收: " + response); // 调试用
        return response;
    }

    /**
     * 查询地址余额
     * 返回格式： "确认的余额, 未确认的余额"
     */
    public String getBalance(String address) throws IOException {
        String response = sendRequest("blockchain.scripthash.get_balance",
                mapper.createArrayNode().add(addressToScriptHash(address)));

        JsonNode root = mapper.readTree(response);
        JsonNode result = root.get("result");

        if (result != null && result.isObject()) {
            long confirmed = result.get("confirmed").asLong() ; // 从聪转换为 BTC
            long unconfirmed = result.get("unconfirmed").asLong() ;
            return confirmed + " BTC, 未确认: " + unconfirmed + " BTC";
        } else {
            return "查询失败: " + response;
        }
    }

    /**
     * 查询地址交易历史
     */
    public String getHistory(String address) throws IOException {
        String response = sendRequest("blockchain.scripthash.get_history",
                mapper.createArrayNode().add(addressToScriptHash(address)));

        JsonNode root = mapper.readTree(response);
        JsonNode result = root.get("result");

        StringBuilder historyBuilder = new StringBuilder();
        if (result != null && result.isArray()) {
            Iterator<JsonNode> it = result.elements();
            while (it.hasNext()) {
                JsonNode tx = it.next();
                historyBuilder.append("交易ID: ").append(tx.get("tx_hash").asText())
                        .append(" | 高度: ").append(tx.get("height").asInt())
                        .append("\n");
            }
        } else {
            historyBuilder.append("无交易记录或查询失败: ").append(response);
        }
        return historyBuilder.toString();
    }

    /**
     * 将比特币地址转换为 Electrum 使用的 scripthash
     * 注意：这是一个简化示例。实际生产环境中需要使用比特币J或其他库进行精确转换。
     * 这里的实现可能不适用于所有地址类型。
     */
    private String addressToScriptHash(String address) {
        // 警告：这是一个占位符实现。
        // 对于主网 P2PKH 地址（以1开头），你可以使用特定的库来正确计算 scripthash。
        // 例如使用 bitcoinj 库： LegacyAddress.fromBase58(params, address).getHash();
        // 这里返回一个示例，你需要替换为正确的转换逻辑。
        System.err.println("警告: addressToScriptHash 需要正确实现！");
        // 临时返回一个空字符串，代码将无法正常工作，直到你实现它。
        return "";
    }
}
